package cn.com.starbucks.basic.config;

import static java.lang.Math.toIntExact;

import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Objects;
import org.apache.commons.lang3.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.codec.JsonJacksonCodec;
import org.redisson.config.Config;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * Description: redis客户端配置
 *
 * @author tecsmile@outlook.com
 * @version 1.0
 * @date 2021/4/16 12:54 下午
 **/
@Configuration
public class RedisClientConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);
        template.setDefaultSerializer(new GenericJackson2JsonRedisSerializer());
        template.setKeySerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new GenericJackson2JsonRedisSerializer());
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        return template;
    }

    //@Bean
    public RedissonClient redissonClient(RedisProperties redisProperties, ObjectMapper objectMapper) {
        Config config = new Config();
        if (Objects.nonNull(redisProperties.getSentinel())) {
            RedisProperties.Sentinel sentinel = redisProperties.getSentinel();
            String[] objects = sentinel.getNodes().stream()
                    .map(i -> String.format("redis://%s", i)).toArray(String[]::new);
            config.useSentinelServers()
                    .setMasterName(sentinel.getMaster())
                    .addSentinelAddress(objects)
                    .setTimeout(toIntExact(redisProperties.getTimeout().toMillis()))
                    .setDatabase(redisProperties.getDatabase());
            if (StringUtils.isNotBlank(redisProperties.getPassword())) {
                config.useSentinelServers().setPassword(redisProperties.getPassword());
            }
        } else {
            String address = String.format("redis://%s:%s", redisProperties.getHost(), redisProperties.getPort());
            config.useSingleServer()
                    .setDatabase(redisProperties.getDatabase())
                    .setTimeout(toIntExact(redisProperties.getTimeout().toMillis()))
                    .setAddress(address);
            if (StringUtils.isNotBlank(redisProperties.getPassword())) {
                config.useSingleServer().setPassword(redisProperties.getPassword());
            }
        }
        config.setCodec(new JsonJacksonCodec(objectMapper));
        return Redisson.create(config);
    }

}
